<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <script>
      //循环异步按序输出
      ~(function () {
        function test() {
          for (var i = 0; i < 5; i++) {
            setTimeout(() => {
              console.log(i)//5
            }, 1000)
          }
        }
        test()
      })()

      ~(function () {
        //第一种解决方式
        function test() {
          for (let i = 0; i < 5; i++) {
            setTimeout(() => {
              console.log(i)//0-4
            }, 1000)
          }
        }
        test()
      })()

      ~(function () {
        //第二种 递归方式
        function test(param) {
          if (param < 5) {
            console.log(param)
            setTimeout(() => {
              test(param + 1)
            })
          }
        }
        test(0)
      })()

      ~(function () {
        //第三种 async  awit
        let fn = function (arr, i) {
          return new Promise(function (resolve, rejct) {
            setTimeout(function () {
              arr.push(i)
              console.log(i)
              resolve()
            }, 1000)
          })
        }
        let test = async function () {
          let arr = []
          for (var i = 0; i < 5; i++) {
            await fn(arr, i)
          }
        }
        test()
      })()

      ~(function () {
        //第四种  generator
        let fn = function (i) {
          return new Promise(function (resolve, rejct) {
            setTimeout(function () {
              resolve(i)
            }, 1000)
          })
        }
        function* Gen() {
          for (var i = 0; i < 5; i++) {
            yield fn(i)
          }
        }
        let runGen = Gen()
        function next() {
          let genobj = runGen.next()
          if (genobj.done) return
          genobj.value.then(function (num) {
            console.log(num)
            next()
          })
        }
        next()


        //循环异步 等待异步全部执行完成后再继续执行往下执行
        ~(function () {
          //异步函数
          function log(info) {
            return new Promise((resolve, reject) => {
              try {
                setTimeout(() => {
                  resolve(`异步${info}`)
                }, 1000)
              } catch (error) {
                reject(error)
              }
            })
          }


          /*
          循环异步 等待异步执行完成后才会往下执行 of for 回调 promise.all 满足
          foreach  map 不满足
          */

          async function fun() {
            [1, 2, 3].forEach(async (i) => {
              const res = await log(i)
              console.log(res)
            })
            console.log('完成')
          }
          fun()

          async function fun() {
            [1, 2, 3].map(async (i) => {
              const res = await log(i)
              console.log(res)
            })
            console.log('完成')
          }
          fun()


          async function fun() {
            for (let i = 0; i < 3; i++) {
              const res = await log(i)
              console.log(res)
            }
            console.log('完成')
          }
          fun()

          async function fun() {
            let arr = [1, 2, 3]
            for (i of arr) {
              const res = await log(i)
              console.log(res)
            }
            console.log('完成')
          }
          fun()

          Promise.all([0, 1, 2].map((reslut) => {
            return new Promise((resolve, reject) => {
              resolve(reslut)
            })
          })).then(res => {
            console.log(res)
            console.log('完成')
          })

          //异步回调
          let count = 0
          let arr = [1, 2, 3]
          let postArr = []
          arr.forEach((item, index) => {
            setTimeout(() => {
              count++
              console.log(item)
              postArr.push(item)
              if (count === arr.length) {
                console.log(postArr)
              }
            }, index * 1000)
          })

        })()
    </script>
  </body>
</html>
